package com.feature50.makeover.chart;

import com.feature50.makeover.ui.CandylandScrollbarUI;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTargetAdapter;
import org.jfree.data.category.CategoryDataset;

import javax.swing.*;
import java.awt.*;

public class BarChart extends Chart {
    private BarChartBars barChart;
    private boolean animated;
    private JScrollPane scrollPane;
    private BarChartLabel label;
    private Animator animator;
    private Animator textAnimator;

    BarChart(BarChartBars barChart, boolean animated) {
        this.barChart = barChart;
        this.animated = animated;
        init();
    }

    private void init() {
        setOpaque(false);

        if (barChart == null) return;

        if (!animated) barChart.setBuilt(1f);

        FormLayout layout = new FormLayout("fill:default:grow", "default, default, fill:default:grow");
        setLayout(layout);

        scrollPane = new JScrollPane(barChart);
        scrollPane.setBorder(null);
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        scrollPane.getVerticalScrollBar().setUI(new CandylandScrollbarUI());
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        add(scrollPane, new CellConstraints().xy(1, 1));
        label = new BarChartLabel(barChart);
        add(label, new CellConstraints().xy(1, 2));

        if (!animated) label.setBuilt(1f);
    }

    public BarChartLabel getLabel() {
        return label;
    }

    public BarChartBars getBars() {
        return barChart;
    }

    public Object getObjectForPoint(int x, int y) {
        Point p = SwingUtilities.convertPoint(this, x, y, barChart);
        return barChart.getObjectForPoint(p.x, p.y);
    }

    public CategoryDataset getModel() {
        return barChart.getModel();
    }

    public void setModel(CategoryDataset model) {
        barChart.setModel(model);
    }

    public void addSelectionListener(BarChartSelectionListener listener) {
        barChart.addSelectionListener(listener);
    }

    public void removeSelectionListener(BarChartSelectionListener listener) {
        barChart.removeSelectionListener(listener);
    }

    public void startBuildAnimation() {
        if (animator != null) animator.cancel();
        if (textAnimator != null) textAnimator.cancel();

        animator = new Animator(1500, new TimingTargetAdapter() {
            public void timingEvent(float v) {
                barChart.setBuilt(v);
                barChart.repaint();
            }

            public void end() {
                barChart.setBuilt(1f);
                barChart.repaint();

                textAnimator = new Animator(500, new TimingTargetAdapter() {
                    public void timingEvent(float v) {
                        label.setBuilt(v);
                        label.repaint();
                    }

                    public void end() {
                        label.setBuilt(1f);
                        label.repaint();
                    }
                });
                textAnimator.setAcceleration(0.3f);
                textAnimator.setAcceleration(0.3f);
                textAnimator.start();
            }
        });
        animator.setAcceleration(0.1f);
        animator.setDeceleration(0.5f);
        animator.start();
    }

    public void abortBuildAnimation() {
        if (animator != null) animator.cancel();
        if (textAnimator != null) textAnimator.cancel();
    }
}
